﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace AK.FTP
{
    public partial class FrmVssSync : Form
    {
        public FrmVssSync()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
        }

        private void btnVssPath_Click(object sender, EventArgs e)
        {
            if (fbdFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtVssPath.Text = fbdFile.SelectedPath;
            }
        }

        private void btnLocalPath_Click(object sender, EventArgs e)
        {
            if (fbdFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtProjectPath.Text = fbdFile.SelectedPath;
            }
        }

        private void btnStartSync_Click(object sender, EventArgs e)
        {
            #region 验证
            if (string.IsNullOrEmpty(txtVssPath.Text))
            {
                MessageBox.Show("VSS目录不能为空");
                txtVssPath.Focus();
                return;
            }

            if (string.IsNullOrEmpty(txtDirPath.Text))
            {
                MessageBox.Show("DIR目录不能为空");
                txtDirPath.Focus();
                return;
            }

            if (string.IsNullOrEmpty(txtVssProjectPath.Text))
            {
                MessageBox.Show("VSS项目目录不能为空");
                txtVssProjectPath.Focus();
                return;
            }

            if (string.IsNullOrEmpty(txtProjectPath.Text))
            {
                MessageBox.Show("本地目录不能为空");
                txtProjectPath.Focus();
                return;
            }

            if (string.IsNullOrEmpty(txtUserName.Text))
            {
                MessageBox.Show("用户名不能为空");
                txtUserName.Focus();
                return;
            }

            if (string.IsNullOrEmpty(txtPassword.Text))
            {
                MessageBox.Show("密码不能为空");
                txtPassword.Focus();
                return;
            }

            if (string.IsNullOrEmpty(txtFiles.Text))
            {
                MessageBox.Show("没有文件需要同步");
                txtFiles.Focus();
                return;
            }
            #endregion

            txtLog.Text = string.Empty;
            Action action = new Action(StartVssSync);
            action.BeginInvoke(new AsyncCallback(EndVssSync), action);
        }

        private void EndVssSync(IAsyncResult iar)
        {
            Action action = (Action)iar.AsyncState;
            action.EndInvoke(iar);
        }

        private void StartVssSync()
        {
            Stopwatch sw = Stopwatch.StartNew();
            foreach (var str in txtFiles.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
            {
                StartVssSync(str);
            }
            CloseProcess("cmd.exe");
            //txtLog.Invoke(new MethodInvoker(() => DisplayMessage(string.Format("本次操作执行完毕，用时:{0}秒", sw.Elapsed.Seconds))));
            DisplayMessage(string.Format("本次操作执行完毕，用时:{0}秒", sw.Elapsed.Seconds));
        }

        private void StartVssSync(string fileName)
        {
            //获取盘符
            string disk = txtProjectPath.Text.Trim().Substring(0,1);
            string path = txtProjectPath.Text + "\\" + fileName;
            int index = path.Replace("/", "\\").LastIndexOf("\\");
            if (index < 0)
            {
                DisplayMessage(string.Format("[{0}]...文件名有误", fileName));
                return;
            }
            
            string[] cmd = new string[] {
                    string.Format("set  path=%PATH%;{0}",txtVssPath.Text),
                    string.Format("set SSDIR={0}",txtDirPath.Text),
                    string.Format("set ssUser={0}",txtUserName.Text),
                    string.Format("set ssPwd={0}",txtPassword.Text),
                    string.Format("{0}:",disk),
                    string.Format("cd {0}",path.Substring(0,index)),
                    string.Format("ss Get {0}",txtVssProjectPath.Text + "\\" + fileName),
                    string.Format("echo ok")
            };

            DisplayMessage(string.Format("[{0}]...{1}", fileName, Cmd(cmd)));
        }

        private void DisplayMessage(string msg)
        {
            if (txtLog.Text.Length != 0)
            {
                msg = "\r\n" + msg;
            }
            txtLog.Invoke(new MethodInvoker(() => txtLog.Text += msg));
        }

        /// <summary>
        /// 运行CMD命令
        /// </summary>
        /// <param name="cmd">命令</param>
        /// <returns></returns>
        public static string Cmd(string[] cmd)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();
            p.StandardInput.AutoFlush = true;
            for (int i = 0; i < cmd.Length; i++)
            {
                p.StandardInput.WriteLine(cmd[i].ToString());
            }
            p.StandardInput.WriteLine("exit");
            string strRst = p.StandardOutput.ReadToEnd();
            p.WaitForExit();
            p.Close();
            return strRst;
        }

        /// <summary>
        /// 关闭进程
        /// </summary>
        /// <param name="ProcName">进程名称</param>
        /// <returns></returns>
        public static bool CloseProcess(string ProcName)
        {
            bool result = false;
            System.Collections.ArrayList procList = new System.Collections.ArrayList();
            string tempName = "";
            int begpos;
            int endpos;
            foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses())
            {
                tempName = thisProc.ToString();
                begpos = tempName.IndexOf("(") + 1;
                endpos = tempName.IndexOf(")");
                tempName = tempName.Substring(begpos, endpos - begpos);
                procList.Add(tempName);
                if (tempName == ProcName)
                {
                    if (!thisProc.CloseMainWindow())
                        thisProc.Kill(); // 当发送关闭窗口命令无效时强行结束进程
                    result = true;
                }
            }
            return result;
        }
    }
}
